/*
 * filter.c
 * Asif Shahidullah
 *
 * Contains function definitions for removing erroneous data
 * and the low pass filter.
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "consecutive.h"
#include "d_list.h"
#include "fcompare.h"
#include "list_data.h"

/* Returns the absolute value of a floating point
 * subtraction operation. */
static __inline__ float fabs_sub (float, float);

int remove_err_data (List list) {
	int i, removed = 0;
	Node curr;

	if (list->size < 2) {
		fprintf (stderr, "Cannot compare less than two data points.\n");
		return 0;
	}

	i = 1;
	curr = list->head->next;	
	while (i < list->size) {
		/* Remove only data points which are greater than 5 degrees off */
		if ( is_consecutive_data_point (curr->prev->data, curr->data) && 
			fcompare (fabs_sub (curr->prev->data->temp, curr->data->temp), 5.0f) > 0) {
			curr = curr->next;
			dealloc_LData(remove_node (list, i));
			removed++;
		} else {
			curr = curr->next;
			i++;
		}
	}
	return removed;
}


void attenuate_data (List list) {
	Node curr;
	int i; 

	/* If we have less than two elements in the list, then
	 * it is impossible to apply the low-pass filter. */
	if (list->size < 2) {
		fprintf (stderr, "Cannot apply low-pass filter to less than "
			"two data points.\n");
		return;
	}

	i = 1;
	curr = list->head->next;
	while (i < list->size) {
	/* Ensure that the filter restarts with every time-break. */
	if (is_consecutive_data_point (curr->prev->data, curr->data)) {
			/* Code taken directly from Roman L.'s site. */
			curr->data->temp = 0.9375f * curr->prev->data->temp + 
				0.0625f * curr->data->temp;
		}
		curr = curr->next;
		i++;
	}
}


/*** Internally defined functions  ***/
float fabs_sub (float op1, float op2) {
	return ((float) fabs(op1 - op2));
}
